package com.etv.launcher.ui.component.status;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.DecelerateInterpolator;

import androidx.annotation.Nullable;

import com.etv.launcher.common.utils.UnitUtil;

public class TVIconView extends View {
    private Drawable mIcon;
    private Paint mBackgroundPaint;
    private float mCornerRadius;
    private boolean mPressed;
    private int mSelectedColor;
    private int mIconPadding;
    private int mViewWidth;
    private int mViewHeight;
    private static final int DEFAULT_SIZE = 40;

    private static final int ANIMATION_DURATION = 400;
    private static final String SELECTED_COLOR = "#0DDDEBF8";
    private static final float PRESSED_ALPHA_VALUE = 0.7f;
    private static final float FOCUSED_ALPHA_VALUE = 1.0f;

    private float mPressedScale = 0.95f;
    private ValueAnimator mPressAnimator;
    private float mCurrentScale = 1.0f;
    private int mNormalAlpha = 255;
    private int mCurrentAlpha = mNormalAlpha;
    private float mPressedAlpha = 0f;
    private boolean mFocused;

    private OnClickListener mClickListener;

    public TVIconView(Context context) {
        this(context, DEFAULT_SIZE, DEFAULT_SIZE);
    }

    public TVIconView(Context context, int widthDp, int heightDp) {
        super(context);
        mViewWidth = UnitUtil.dpToPx(getResources(), widthDp);
        mViewHeight = UnitUtil.dpToPx(getResources(), heightDp);
        init();
    }

    public TVIconView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public TVIconView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mViewWidth = UnitUtil.dpToPx(getResources(), DEFAULT_SIZE);
        mViewHeight = UnitUtil.dpToPx(getResources(), DEFAULT_SIZE);
        init();
    }

    private void init() {
        //背景
        mBackgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mBackgroundPaint.setStyle(Paint.Style.FILL);

        //圆角
        mCornerRadius = UnitUtil.dpToPx(getResources(), Math.min(mViewHeight, mViewWidth) * 0.1f);

        //选中眼神凶恶
        mSelectedColor = Color.parseColor(SELECTED_COLOR);

        //padding
        mIconPadding = UnitUtil.dpToPx(getResources(), 4);

        //设置可点击，允许焦点
        setFocusable(true);
        setFocusableInTouchMode(true);
        setClickable(true);

        //置空背景
        setBackground(null);

        //初始化动画
        setupAnimators();
    }

    @Override
    protected void dispatchSetPressed(boolean pressed) {
        if (pressed != mPressed) {
            mPressed = pressed;
            invalidate();
        }
    }

    /**
     * 初始化动画
     */
    private void setupAnimators() {
        //按下动画
        mPressAnimator = ValueAnimator.ofFloat(0f, 1f);
        //持续时间
        mPressAnimator.setDuration(ANIMATION_DURATION);
        mPressAnimator.setInterpolator(new DecelerateInterpolator());

        //设置监听器
        mPressAnimator.addUpdateListener(animation -> {
            float fraction = (float) animation.getAnimatedValue();
            if (mPressed) {
                mCurrentScale = 1f - (1f - mPressedScale) * fraction;
                if (!mFocused) {
                    mPressedAlpha = fraction * PRESSED_ALPHA_VALUE;
                }
            } else {
                mCurrentScale = mPressedScale + (1f - mPressedScale) * fraction;
                if (!mFocused) {
                    // 直接从当前alpha值开始渐变到0
                    mPressedAlpha = (1f - fraction) * mPressedAlpha;
                }
            }
            invalidate();
        });
    }


    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int width = resolveSize(mViewWidth, widthMeasureSpec);
        int height = resolveSize(mViewHeight, heightMeasureSpec);
        setMeasuredDimension(width, height);
    }

    /**
     * 按下
     * @param keyCode a key code that represents the button pressed, from
     *                {@link android.view.KeyEvent}
     * @param event the KeyEvent object that defines the button action
     * @return
     */
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_ENTER || keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
            if (!mPressed) {
                mPressed = true;
                startPressAnimation(true);
                return true;
            }
        }
        return super.onKeyDown(keyCode, event);
    }

    /**
     * 释放
     * @param keyCode A key code that represents the button pressed, from
     *                {@link android.view.KeyEvent}.
     * @param event   The KeyEvent object that defines the button action.
     * @return
     */
    @Override
    public boolean onKeyUp(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_ENTER || keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
            if (mPressed) {
                mPressed = false;
                startPressAnimation(false);
                performClick();
                return true;
            }
        }
        return super.onKeyUp(keyCode, event);
    }

    @Override
    @SuppressLint("MissingSuperCall")
    protected void onFocusChanged(boolean gainFocus, int direction, @Nullable Rect previouslyFocusedRect) {
        mFocused = gainFocus;
        if (mPressAnimator.isRunning()) {
            mPressAnimator.cancel();
        }
        // 失去焦点时重置所有状态
        if (!gainFocus) {
            mPressed = false;
            mPressedAlpha = 0f;
            mCurrentScale = 1.0f;
        }
        invalidate();
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (!isEnabled()) {
            return false;
        }

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                // 请求焦点，这会导致之前有焦点的视图失去焦点
                requestFocus();
                mPressed = true;
                startPressAnimation(true);
                break;
            case MotionEvent.ACTION_UP:
                if (mPressed) {
                    mPressed = false;
                    startPressAnimation(false);
                    performClick();
                }
                break;
            case MotionEvent.ACTION_CANCEL:
                mPressed = false;
                startPressAnimation(false);
                break;
        }
        return true;
    }

    private void startPressAnimation(boolean pressed) {
        if (mPressAnimator != null) {
            // 保存当前的alpha值，用于平滑过渡
            float currentAlpha = mPressedAlpha;
            mPressAnimator.cancel();

            // 设置初始alpha值
            if (!pressed) {
                mPressedAlpha = currentAlpha;
            }

            if (pressed) {
                mPressAnimator.setFloatValues(0f, 1f);
            } else {
                mPressAnimator.setFloatValues(0f, 1f); // 总是从0到1，区别在于动画更新时的计算
            }
            mPressAnimator.start();
        }
    }

    @Override
    public boolean performClick() {
        super.performClick();
        if (mClickListener != null) {
            mClickListener.onClick(this);
        }
        return true;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        canvas.save();

        if (mPressed || mCurrentScale != 1.0f) {
            float px = getWidth() / 2f;
            float py = getHeight() / 2f;
            canvas.scale(mCurrentScale, mCurrentScale, px, py);
        }

        // 优化背景绘制逻辑
        if (mFocused || mPressed || mPressedAlpha > 0.01f) {
            mBackgroundPaint.setColor(mSelectedColor);
            // 如果有焦点，始终使用焦点状态的alpha
            float alpha = mFocused ? FOCUSED_ALPHA_VALUE : mPressedAlpha;
            mBackgroundPaint.setAlpha((int) (255 * alpha));
            canvas.drawRoundRect(0, 0, getWidth(), getHeight(),
                    mCornerRadius, mCornerRadius, mBackgroundPaint);
        }

        if (mIcon != null) {
            int iconWidth = getWidth() - (mIconPadding * 2);
            int iconHeight = getHeight() - (mIconPadding * 2);
            mIcon.setBounds(mIconPadding, mIconPadding,
                    mIconPadding + iconWidth, mIconPadding + iconHeight);
            mIcon.setAlpha(mCurrentAlpha);
            mIcon.draw(canvas);
        }

        canvas.restore();
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        if (mPressAnimator != null) {
            mPressAnimator.cancel();
            mPressAnimator = null;
        }
    }

    @Override
    public void setOnClickListener(OnClickListener listener) {
        mClickListener = listener;
    }

    public void setViewSize(int widthDp, int heightDp) {
        mViewWidth = UnitUtil.dpToPx(getResources(), widthDp);
        mViewHeight = UnitUtil.dpToPx(getResources(), heightDp);
        requestLayout();
    }

    public void setIcon(Drawable icon) {
        mIcon = icon;
        invalidate();
    }

}